open Hashtbl
open Syntax
open BlockPopulation.GenePool
open TestCases
open Rules

open ProofAssembler.ProoProg
module Genotypes : sig
	type genoStatus = Dead of float | Alive of float | Unborn
	type genotype = program
	type genotype_evaluation = NoEval 
		| EvalFunc of float * (term -> float)
		| TestCases of test_case list
	val string_of_genotype : ?separator:string -> gene_pool->genotype->string
end  			


open ProofAssembler.Proof
module Species : sig
	type species_info = {
		species_id : int;
		ancestor_species_id : int option;
		mutable fillProportion : float;
		mutable theoreticalMaxFill : int;
		mutable currentFill : int;
		mutable avgComplexity : float;
		mutable avgFitness : float;
	}	
	type population = {
		pattern : proof;
		genotypes : (Genotypes.genotype, Genotypes.genoStatus) t ;
		mutable info : species_info;
		mutable contains_solution : bool
	}
	val card_population : ?pred:(Genotypes.genoStatus->bool) -> population -> int
	val get_live : population -> (float * Genotypes.genotype) list
end

module GP : sig
	type ecoSetting = {
		maxProofWidth : int;
		aprNumberOfLiveGenotypes : int;
		aprGenePoolTotComp : int;
		(*Sel_1*) elitismSize : int;
		selectSize : int;
		selectReap : int
	}
	type ecosystem  = {
		mutable solutions : term list;
		mutable species_count : int;
		mutable generation_count : int;
		mutable stats : string;
		mutable genotype_evaluator : Genotypes.genotype_evaluation;
		fossil_record : (proof , int option) t;
		settings : ecoSetting;
		goal_type : ty; 
		genes : gene_pool ref; 
		kingdom : (proof,  Species.population) t  
	}	
	val card_ecosystem : ?pred:(Genotypes.genoStatus->bool) -> ecosystem -> int

	val get_species_from_id : ecosystem->int->proof
	val add_species : ?debug:bool ->ecosystem -> proof -> int option -> int * int option

	val ghost_ecosystem : gene_pool ref -> ecosystem
	val modifyProofs : ?proofs:(proof list) -> ecosystem->int->(int option * proof) list
	val make_ecosystem : ?debug:bool -> gene_pool ref->
							ty->Genotypes.genotype_evaluation->ecoSetting -> ecosystem
end

open GP
module GPRun : sig	
	val next_generation : ?debug:bool -> ecosystem -> constraint_function->unit
end
